package cn.caplike.demo.nio._2017;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;

/**
 * 简介：Selector
 *
 * @author 李珂 2017年11月22日 下午4:00:31
 */
public class SocketChannelTest {

    public static void clientRun() throws IOException {
        SocketChannel channel = SocketChannel.open();// 通过open()打开SocketChannel
        channel.connect(new InetSocketAddress("127.0.0.1", 5000));
        channel.configureBlocking(false);

        while (!channel.finishConnect()) {
            // do sth. else
        }

        /*
         * 利用SocketChannel进行数据操作
         * 在非阻塞模式下，read()和write()没有进行任何操作就返回了，所以要在循环中调用，并注意返回值。
         */
        ByteBuffer buf = ByteBuffer.allocate(48);

        buf.put(("Hi, caplike. (" + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new GregorianCalendar().getTime()) + ")").getBytes());
        buf.flip();
        while (buf.hasRemaining()) {
            channel.write(buf);
        }
        channel.close();
    }

    public static void serverRun() throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 绑定主机端口
        serverSocketChannel.socket().bind(new InetSocketAddress(5000));
        serverSocketChannel.configureBlocking(false);

        System.out.println("Server: listening...");
        while (true) {
            ByteBuffer buf = ByteBuffer.allocate(48);
            // accept()在非阻塞模式中，若建立连接，则返回SocketChannel；否则返回null
            SocketChannel socketChannel = serverSocketChannel.accept();
            if (socketChannel != null) {
                // 利用SocketChannel进行数据操作
                socketChannel.read(buf);
                System.out.println("Client: " + new String(buf.array(), StandardCharsets.UTF_8));
            }
        }
    }

}
